Add length check in Doc::data_len()#13133
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a defensive length check to Doc::data_len() in the cache layer so malformed Doc::len / hlen combinations no longer underflow when computing payload length.
Changes:
- Add a guard in
Doc::data_len()to return0when the fragment length is not large enough to contain theDocprefix plus header. - Preserve the existing payload-length computation for valid cache documents.
bryancall
left a comment
There was a problem hiding this comment.
Good hardening. len is the unrounded on-disk fragment length (uint32_t), and since sizeof(self_type) is size_t, this->len - sizeof(self_type) - this->hlen promotes to 64-bit and underflows to a huge value when len < sizeof(Doc) + hlen, then truncates back to a bogus large uint32_t. On a corrupt or truncated doc that bogus length flows into new_IOBufferBlock() sizes and read lengths in StripeSM/CacheRead, so clamping to 0 closes an over-read. Boundary is right: <= returns 0 at equality, which is what the subtraction produced there anyway, and the callers I checked all tolerate a 0-length result.
Worth a follow-up: the deeper fix is to validate len >= prefix_len() once when the Doc is read off the stripe and treat a violation as a cache miss, rather than hardening the accessor (similar to the recent m_frag_offset_count unmarshal validation). Two related spots share this: test_Stripe.cc sizes allocations directly from data_len(), and traffic_cache_tool/CacheDefs.cc has an independent copy of Doc::data_len() with the same underflow.
|
We need to decide what we should do with |
To avoid underflow.